home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1985-1992 New York University
- *
- * This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
- * warranty (none) and distribution info and also the GNU General Public
- * License for more details.
-
- */
- #define GEN
-
- #include "hdr.h"
- #include "libhdr.h"
- #include "vars.h"
- #include "gvars.h"
- #include "attr.h"
- #include "gmainprots.h"
- #include "setprots.h"
- #include "miscprots.h"
- #include "gnodesprots.h"
- #include "gutilprots.h"
- #include "gmiscprots.h"
- #include "initobjprots.h"
- #include "arithprots.h"
- #include "chapprots.h"
- #include "smiscprots.h"
- #include "expandprots.h"
-
- static Tuple constrained_type(Symbol, Node, Node);
- static int array_nelem(Node);
- static void replace_name(Node, Symbol, Symbol);
-
- static int array_nelem_defined; /* set if array_nelem undefined */
-
- void expand_line() /*;expand_line*/
- {
- /* called when expander reaches line debug_line if debug_line is not
- * zero. This is meant to provide useful trapping point for
- * interactive debugging. ds 7-19-85
- */
- }
-
-
- int in_bin_ops(Symbol op) /*;in_bin_ops*/
- {
- /* bin_ops = {'and', 'or', 'xor', '&', '&ac', '&ca', &cc'
- * '=', '/=', '<=', '>', '>=', '<',
- * '+i', '-i', '*i', '/i', '**i', 'remi', 'modi',
- * '+fl', '-fl', '*fl', '/fl', '**fl',
- * '+fx', '-fx', '*fx', '/fx', '*fix', '*fxi', '/fxi'},
- */
- return op == symbol_and || op == symbol_or || op == symbol_xor
- || op == symbol_cat || op == symbol_cat_cc || op == symbol_cat_ca
- || op == symbol_cat_ac || op == symbol_eq || op == symbol_ne
- || op == symbol_le || op == symbol_gt || op == symbol_ge
- || op == symbol_lt || op == symbol_addi || op == symbol_subi
- || op == symbol_muli || op == symbol_divi || op == symbol_expi
- || op == symbol_remi || op == symbol_modi || op == symbol_addfl
- ||op == symbol_subfl || op == symbol_mulfl || op == symbol_divfl
- || op == symbol_expfl || op == symbol_addfx || op == symbol_subfx
- || op == symbol_mulfx || op == symbol_divfx || op == symbol_mulfix
- || op == symbol_mulfxi || op == symbol_divfxi;
- }
-
- int in_un_ops(Symbol op) /*;in_un_ops*/
- {
- /* un_ops = {'not', '-ui', '+ui', 'absi', '-ufl', '+ufl', 'absfl',
- * '-ufx', '+ufx', 'absfx' };
- */
-
- return op == symbol_not || op == symbol_subui || op == symbol_addui
- || op == symbol_absi || op == symbol_subufl || op == symbol_addufl
- || op == symbol_absfl || op == symbol_subufx || op == symbol_addufx
- || op == symbol_absfx;
- }
-
- void expand_block(Node decl_node, Node stmt_node, Node exc_node, Node term_node)
- /*;expand_block*/
- {
- Node stmt_list_node;
-
- if (decl_node != OPT_NODE)
- expand(decl_node);
-
- stmt_list_node = N_AST1(stmt_node);
- N_LIST(stmt_list_node) = tup_with(N_LIST(stmt_list_node),
- (char *) copy_tree(term_node));
- expand(stmt_node);
-
- if (exc_node != OPT_NODE) {
- /* Note: exc node may be a sequence of statements */
- if (N_KIND(exc_node) == as_exception) {
- N_AST1(exc_node) = term_node;
- if (N_AST2_DEFINED(as_exception)) N_AST2(exc_node) = (Node) 0;
- if (N_AST3_DEFINED(as_exception)) N_AST3(exc_node) = (Node) 0;
- if (N_AST4_DEFINED(as_exception)) N_AST4(exc_node) = (Node) 0;
- }
- expand(exc_node);
- }
- }
-
- static Tuple constrained_type(Symbol array_type, Node lbd_node, Node ubd_node)
- /*;constrained_type*/
- {
- /*
- * Given an unconstrained array type, constructs a constrained subtype
- * with the given bounds.
- * returns [type_name, decls] where type_name is the name of the
- * constrained array subtype, and decls a list (tuple) of nodes necessary
- * to elaborate the type.
- */
-
- Symbol bt, index_name, array_name, comp_type;
- Node range_node, indic_node, ix_name_node, index_node, ar_name_node,
- array_node;
- Tuple tup, dtup;
-
- bt = base_type(N_TYPE(lbd_node));
-
- /* 1- Create range node */
- range_node = node_new(as_range);
- N_AST1(range_node) = lbd_node;
- N_AST2(range_node) = ubd_node;
- indic_node = node_new(as_subtype_indic);
- N_AST1(indic_node) = new_name_node(bt);
- N_AST2(indic_node) = range_node;
-
- /* 2- Create index subtype */
- index_name = new_unique_name("index");
- ix_name_node = new_name_node(index_name);
- index_node = node_new(as_subtype_decl);
- N_AST1(index_node) = ix_name_node;
- N_AST2(index_node) = indic_node;
- tup = constraint_new(co_range);
- tup[2] = (char *) lbd_node;
- tup[3] = (char *) ubd_node;
- new_symbol(index_name, na_subtype, bt, tup, ALIAS(bt));
- CONTAINS_TASK(index_name) = FALSE;
-
- /* 3- Create constrained array subtype */
- indic_node = node_new(as_constraint);
- N_LIST(indic_node) = tup_new1( (char *) new_name_node(index_name));
- array_name = new_unique_name("array");
- ar_name_node = new_name_node(array_name);
- array_node = node_new(as_subtype_decl);
- N_AST1(array_node) = ar_name_node;
- N_AST2(array_node) = indic_node;
- comp_type = (Symbol) (SIGNATURE(array_type))[2];
- tup = tup_new(2);
- tup[1] = (char *) tup_new1( (char *) index_name);
- tup[2] = (char *) comp_type;
- new_symbol(array_name, na_subtype, array_type,
- tup, ALIAS(array_type));
- CONTAINS_TASK(array_name) = CONTAINS_TASK(array_type);
- dtup = tup_new(2);
- dtup[1] = (char *) index_node;
- dtup[2] = (char *) array_node;
- tup = tup_new(2);
- tup[1] = (char *) array_name;
- tup[2] = (char *) dtup;
- return tup;
- }
-
- static int array_nelem(Node node) /*;array_nelem*/
- {
- /*
- * Given a node that is appropriate for an array type, determines the
- * number of elements if known statically, returns OM otherwise.
- */
-
- Symbol node_name, type_name, index_sym;
- Tuple index_list, tup;
- int size, nk;
- Node nod2, lbd_node, ubd_node;
- Fortup ft1;
- Const lbd, ubd;
-
- /* the global (to this module) variable array_nelem_defined is set to
- * FALSE if the SETL version of this procedure returns OM, TRUE otherwise
- */
- array_nelem_defined = TRUE; /* assume defined */
- nk = N_KIND(node);
- if (nk == as_subtype_indic) {
- nk = (int) N_KIND((N_AST2(node) == OPT_NODE) ?
- N_AST1(node) : N_AST2(node));
- nod2 = N_AST2(node);
- }
- if (nk == as_string_ivalue) {
- return tup_size((Tuple) N_VAL(node));
- }
- else if (nk == as_simple_name) {
- node_name = N_UNQ(node);
- if (NATURE(node_name) == na_type) {
- array_nelem_defined = FALSE;
- return 0; /* always unconstrained */
- }
- else if ( NATURE(node_name) == na_subtype) {
- type_name = node_name;
- }
- else { /* object */
- type_name = N_TYPE(node);
- }
- tup = SIGNATURE(type_name);
- index_list = (Tuple) tup[1];
- size = 1;
- FORTUP(index_sym = (Symbol), index_list, ft1);
- tup = SIGNATURE(index_sym);
- lbd_node = (Node) tup[2];
- ubd_node = (Node) tup[3];
- lbd = get_ivalue(lbd_node);
- ubd = get_ivalue(ubd_node);
- if (lbd->const_kind != CONST_OM && ubd->const_kind != CONST_OM) {
- if (get_ivalue_int(ubd_node) < get_ivalue_int(lbd_node))
- return 0;
- else
- size *= get_ivalue_int(ubd_node)-get_ivalue_int(lbd_node)+1;
- }
- else{
- array_nelem_defined = FALSE;
- return 0;
- }
- ENDFORTUP(ft1);
- return size;
- }
- #ifdef TBSL
- /* Wrong because the type_name is the base_type*/
- else if (nk == as_array_aggregate || nk == as_array_ivalue) {
- type_name = N_TYPE(node);
- tup = SIGNATURE(type_name);
- index_list = (Tuple) tup[1];
- size = 1;
- FORTUP(index_sym = (Symbol), index_list, ft1);
- tup = SIGNATURE(index_sym);
- lbd_node = (Node) tup[2];
- ubd_node = (Node) tup[3];
- lbd = get_ivalue(lbd_node);
- ubd = get_ivalue(ubd_node);
- if (lbd->const_kind != CONST_OM &&
- ubd->const_kind != CONST_OM) {
- if (get_ivalue_int(ubd_node) < get_ivalue_int(lbd_node)) {
- return 0;
- }
- else {
- size *= get_ivalue_int(ubd_node) - get_ivalue_int(lbd_node) +1;
- }
- }
- else{
- array_nelem_defined = FALSE;
- return 0;
- }
- ENDFORTUP(ft1);
- return size;
- }
- #endif
- else if (nk == as_range) {
- lbd_node = N_AST1(nod2);
- ubd_node = N_AST2(nod2);
- size = 1;
- lbd = get_ivalue(lbd_node);
- ubd = get_ivalue(ubd_node);
- if (lbd->const_kind != CONST_OM && ubd->const_kind != CONST_OM) {
- if (get_ivalue_int(ubd_node) < get_ivalue_int(lbd_node))
- return 0;
- else
- size *= get_ivalue_int(ubd_node) - get_ivalue_int(lbd_node) +1;
- }
- else{
- array_nelem_defined = FALSE;
- return 0;
- }
- return size;
- }
- else {
- /*compiler_error_k("Array_nelem: kind = ", node);*/
- /*TBSL : does not make the test for a slice,
- *a convert, a call, an op.
- */
- array_nelem_defined = FALSE;
- return 0;
- }
- }
-
- Symbol op_kind(Node node) /*;op_kind*/
- {
- /* Given a as_op node, returns the unique name of the operator */
-
- Node id_node;
-
- id_node = N_AST1(node);
- return N_UNQ(id_node);
- }
-
- static void replace_name(Node node, Symbol old_name, Symbol new_name)
- /*;replace_name*/
- {
- /* Replaces all occurences of old_name by new_name in the tree rooted at
- * node.
- */
-
- Node subnode;
- Fortup ft1;
- int nk;
-
- if (node == (Node)0)
- chaos("replace_name called on null node");
- if (N_UNQ(node) == old_name )
- N_UNQ(node) = new_name;
-
- nk = N_KIND(node);
- if (N_AST1_DEFINED(nk) && N_AST1(node) != (Node)0)
- replace_name(N_AST1(node), old_name, new_name);
- if (N_AST2_DEFINED(nk) && N_AST2(node) != (Node)0)
- replace_name(N_AST2(node), old_name, new_name);
- if (N_AST3_DEFINED(nk) && N_AST3(node) != (Node)0)
- replace_name(N_AST3(node), old_name, new_name);
- if (N_AST4_DEFINED(nk) && N_AST4(node) != (Node)0)
- replace_name(N_AST4(node), old_name, new_name);
- if (N_LIST_DEFINED(nk) && N_LIST(node) != (Tuple)0) {
- FORTUP(subnode = (Node), N_LIST(node), ft1);
- replace_name(subnode, old_name, new_name);
- ENDFORTUP(ft1);
- }
- }
-
- void mint(Node node) /*;mint*/
- {
- /* Deletes all occurences of :
- * as_qualify, as_name, as_conditon, as_parenthesis
- * in the tree rooted at node.
- */
-
- register int i, nk;
- Tuple tup;
-
- nk= N_KIND(node);
- if (N_AST1_DEFINED(nk) && N_AST1(node) != (Node)0) mint(N_AST1(node));
- if (N_AST2_DEFINED(nk) && N_AST2(node) != (Node)0) mint(N_AST2(node));
- if (N_AST3_DEFINED(nk) && N_AST3(node) != (Node)0) mint(N_AST3(node));
- if (N_AST4_DEFINED(nk) && N_AST4(node) != (Node)0) mint(N_AST4(node));
- if (N_LIST_DEFINED(nk) && N_LIST(node) != (Tuple)0) {
- tup = N_LIST(node);
- for (i = (int)*tup++; i > 0; i--)
- mint((Node)*tup++);
- }
-
- if (nk == as_name || nk == as_parenthesis || nk == as_condition)
- copy_attributes(N_AST1(node), node);
- else if (nk == as_qualify)
- copy_attributes(N_AST2(node), node);
- }
-
- void check_priv_instance(Tuple must_constrain, Symbolmap instance_map)
- /*;check_priv_instance*/
- {
- /*
- * For a late instantiation, verify that a private generic type that is
- * used to declare an object has been instantiated with a constrained
- * type.
- */
-
- Fortup ft1;
- Symbol g_name, new_type;
-
- FORTUP(g_name = (Symbol), must_constrain, ft1);
- if (tup_mem((char *)g_name, must_constrain) ) {
- new_type = symbolmap_get(instance_map, g_name);
- if ( NATURE(new_type) == na_array
- || (NATURE(new_type) == na_record && has_discriminants(new_type)
- && (Node) default_expr((Symbol)discriminant_list(new_type)[2])
- /* this is 1st discrim, as 'constrained' is added by expander */
- == OPT_NODE )) {
- user_error(
- "usage of generic private type requires instantiation with constrained type");
- }
- }
- ENDFORTUP(ft1);
- }
-
- void expand_decl(Node node) /*;expand_decl*/
- {
- Fortup ft1;
- Node id_list_node, type_indic_node, init_node, first_obj_node,
- const_val_node, decl_node, id_node, constrained_node;
- Symbol init_type_name, first_obj_name, type_name, p;
- Tuple tup;
- int is_var_decl, init_len, init_len_defined,
- const_len, const_len_defined, is_agg;
-
- /* Note: const decl are always single declarations (split by FE).
- * otherwise, the case of deferred constants would be more
- * difficult.
- */
- id_list_node = N_AST1(node);
- type_indic_node = N_AST2(node);
- init_node = N_AST3(node);
- init_type_name = N_TYPE(init_node);
- is_var_decl = N_KIND(node) == as_obj_decl;
- first_obj_node = (Node) ((Tuple) N_LIST(id_list_node))[1];
- first_obj_name = N_UNQ(first_obj_node);
- type_name = TYPE_OF(first_obj_name);
-
- if (!is_var_decl && init_node == OPT_NODE) {
- /*
- * Deferred constant: transform into variable, as it has no
- * initialization and cannot be unconstrained (LRM 7.4.1(3))
- * Defer elaboration of this "variable" after elaboration of the
- * type, but before elaboration of any delayed type depending on
- * the same type.
- */
- N_KIND(node) = as_obj_decl;
- emap_put(first_obj_name , (char *) TRUE);
- #ifdef TBSN
- emap_defined = emap_get(type_name);
- etup = EMAP_VALUE;
- if (!emap_defined || tup_size(etup) == 0) {
- ntup = tup_new1((char *) copy_node(node));
- }
- else {
- ntup = tup_new(tup_size(etup)+1);
- ntup[1] = (char *)copy_node(node);
- for (tupi = 1; tupi <= tup_size(etup); tupi++) {
- ntup[tupi+1] = etup[tupi];
- }
- }
- emap_put(type_name, (char *) ntup);
- delete_node(node);
- #endif
- }
- else if (!is_var_decl && emap_get(first_obj_name)) {
- /*
- * Full declaration of a deferred constant,
- * transform into assignment.
- */
- if (is_simple_type(type_name)) {
- make_assign_node(node, first_obj_node, init_node);
- expand(node);
- N_SIDE(node) = N_SIDE(init_node);
- }
- else {
- if (init_node == OPT_NODE) {
- /* record type */
- N_SIDE(node) = FALSE;
- }
- else {
- N_AST3(node) = OPT_NODE;
- expand(init_node);
- N_SIDE(node) = N_SIDE(init_node);
- make_insert_node(node, tup_new1((char *)copy_node(node)),
- new_assign_node(first_obj_node, init_node));
- }
- }
- return;
- }
-
- /*
- * Normal declaration.
- * Remark: following tests are always FALSE for constants
- */
- if (is_task_type(type_name)) {
- /* Initial value for task objects is create_task */
- init_node = (Node) new_create_task_node(type_name);
- N_AST1(node) = id_list_node;
- N_AST2(node) = type_indic_node;
- N_AST3(node) = init_node;
- }
- else if (is_access_type(type_name) && init_node == OPT_NODE) {
- /* Initial value for (uninitialized) access objects is null*/
- init_node = (Node) new_null_node(type_name);
- N_AST1(node) = id_list_node;
- N_AST2(node) = type_indic_node;
- N_AST3(node) = init_node;
- }
-
- /*
- * Remark: type_name always constrained for variables
- */
- if (is_array_type(type_name) && init_node != OPT_NODE) {
- /* Try to propagate constraints statically */
- if (!is_unconstrained(type_name) && is_unconstrained(init_type_name)) {
- init_len = array_nelem(init_node);
- init_len_defined = array_nelem_defined;
- const_len = array_nelem(type_indic_node);
- const_len_defined = array_nelem_defined;
- if (init_len_defined && const_len_defined) {
- if (init_len == const_len) {
- N_TYPE(init_node) = type_name;
- }
- else {
- make_raise_node(init_node, symbol_constraint_error);
- USER_WARNING("Mismatched length will raise",
- " CONSTRAINT_ERROR");
- }
- }
- }
- else if (is_unconstrained(type_name) &&
- !is_unconstrained(init_type_name)) {
- N_UNQ(type_indic_node) = init_type_name;
- FORTUP(id_node = (Node), N_LIST(id_list_node), ft1);
- TYPE_OF(N_UNQ(id_node)) = init_type_name;
- ENDFORTUP(ft1);
- }
- }
-
- expand(type_indic_node);
- N_SIDE(node) = N_SIDE(type_indic_node);
- p = INIT_PROC((Symbol) base_type(type_name));
- if (init_node == OPT_NODE && p != (Symbol)0) {
- init_node = build_init_call(first_obj_node, p, type_name, OPT_NODE);
- expand(init_node);
- N_AST1(node) = id_list_node;
- N_AST2(node) = type_indic_node;
- N_AST3(node) = init_node;
- decl_node = node;
- }
- else if (init_node != OPT_NODE ) {
- is_agg = is_aggregate(init_node); /* may become an insert */
- expand(init_node);
- init_type_name = N_TYPE(init_node);
- if (is_agg) {
- replace_name(init_node, N_UNQ(init_node), first_obj_name);
- }
- if (is_agg && is_record_type(type_name) && is_unconstrained(type_name)){
- if (N_KIND(node) == as_obj_decl) {
- /* Correct bit constrained in aggregate if unconstrained var */
- if (N_KIND(init_node) == as_insert ) {
- tup = N_LIST(N_AST1(N_AST1(N_AST1(init_node))));
- }
- else if ( N_KIND(init_node) == as_record_ivalue
- || N_KIND(init_node) == as_record_aggregate) {
- tup = N_LIST(N_AST1(N_AST1(init_node)));
- }
- else
- chaos("not so impossible expand2 problem");
- constrained_node = (Node) tup[1];
- const_val_node = N_AST2(constrained_node);
- N_VAL(const_val_node) = (char *) int_const(FALSE);
- }
- else if (NATURE(type_name) == na_record
- && N_KIND(node) == as_const_decl) {
- /* Propagate type of aggregate to constant */
- TYPE_OF(first_obj_name) = init_type_name;
- N_UNQ(type_indic_node) = init_type_name;
- }
- }
- /* Propagate possible pre-statements in front of this node*/
- if (N_KIND(init_node) == as_insert) {
- propagate_insert(init_node, node);
- decl_node = N_AST1(node);
- }
- else {
- decl_node = node;
- }
- N_SIDE(node) |= N_SIDE(init_node);
- if (is_array_type(type_name)
- && is_unconstrained(type_name) && !is_unconstrained(init_type_name)) {
- /*
- * Lucky! expand of init_node has been able to determine
- * the constraints...
- */
- N_UNQ(type_indic_node) = init_type_name;
- FORTUP(id_node = (Node), N_LIST(id_list_node), ft1);
- TYPE_OF(N_UNQ(id_node)) = init_type_name;
- ENDFORTUP(ft1);
- }
- }
- else {
- decl_node = node;
- }
-
- /* If side-effect, replace by a list of single object decl.*/
- if (N_SIDE(decl_node))
- make_single_decl_list(node, decl_node);
- }
-
- void expand_type(Node node) /*;expand_type*/
- {
- Fortup ft1;
- Node id_node, small_node, proc_init_node, invariant_node,
- variant_node, comp_node, delayed_node;
- Node cases_node, case_node;
- Symbol type_name, parent_type, comp_name, dummy;
- Tuple sig, tup, discr_list;
- int nat;
-
- /* Generate complete declaration if simple derivation is not enough*/
- id_node = N_AST1(node);
- type_name = N_UNQ(id_node);
-
- N_SIDE(node) = FALSE;
- CONTAINS_TASK(type_name) = FALSE;
-
- if (TYPE_OF(type_name) == symbol_incomplete) {
- /* case of an incomplete type in the private part of a package,
- * whose complete type declaration has appeared in the body,
- * and saved in a dummy symbol. Retrieve, and update the entry
- * for the type.
- */
- dummy = N_TYPE(node);
- NATURE(type_name) = NATURE(dummy);
- TYPE_OF(type_name) = TYPE_OF(dummy);
- SIGNATURE(type_name) = SIGNATURE(dummy);
- OVERLOADS(type_name) = OVERLOADS(dummy);
- root_type(type_name) = root_type(dummy);
- }
- parent_type = TYPE_OF(type_name);
- nat = NATURE(type_name);
- if (nat == na_type) {
- /* Derived or predefined type*/
- if (is_fixed_type(type_name)) {
- /* Provide small if no representation clause*/
- sig = SIGNATURE(type_name);
- small_node = (Node) sig[5];
- if (small_node == OPT_NODE) {
- /* Processing formerly done here now down by new_fixed_type()
- * in adasem, so it is an error to reach here.
- */
- chaos("fixed with small OPT_NODE");
- }
- CONTAINS_TASK(type_name) = (char *) FALSE;
- }
- else if (CONTAINS_TASK(parent_type) /* derived access on task*/
- && is_access_type(parent_type)) { /* needs own template*/
- NATURE(type_name) = na_access;
- SIGNATURE(type_name) = SIGNATURE(parent_type);
- CONTAINS_TASK(type_name) = (char *) TRUE;
- }
- else {
- CONTAINS_TASK(type_name) = CONTAINS_TASK(parent_type);
- SIGNATURE(type_name) = SIGNATURE(parent_type);
- INIT_PROC(type_name) = INIT_PROC(parent_type);
- }
- }
- else if (nat == na_array) {
- comp_name = (Symbol) ((Tuple) SIGNATURE(type_name))[2];
- CONTAINS_TASK(type_name) = CONTAINS_TASK(comp_name);
- proc_init_node = build_proc_init_ara(type_name);
- if (proc_init_node != OPT_NODE) {
- expand(proc_init_node);
- make_insert_node(node, tup_new1((char *) copy_node(node)),
- proc_init_node);
- }
- }
- else if (nat == na_record) {
- /* review following code: only altering 2nd part of SIGNATURE */
- sig = SIGNATURE(type_name);
- discr_list = (Tuple) sig[3];
- invariant_node = (Node) sig[1];
- variant_node = (Node) sig[2];
-
- FORTUP(comp_node= (Node), N_LIST(invariant_node), ft1);
- expand(comp_node);
- N_SIDE(node) |= N_SIDE(comp_node);
- ENDFORTUP(ft1);
- /* In case of a variant part of the type:
- * case disc is
- * when a..b => null;
- * end case;
- * the record type is said to have no variant part.
- */
- if (variant_node != OPT_NODE) {
- cases_node = N_AST2(variant_node);
- tup = tup_copy(N_LIST(cases_node));
- case_node = (Node) tup_fromb(tup);
- comp_node = N_AST2(case_node);
- if (tup_size(tup) == 0
- && N_AST1(comp_node) == OPT_NODE
- && N_AST2(comp_node) == OPT_NODE) {
- variant_node = OPT_NODE;
- SIGNATURE(type_name)[2] = (char *) variant_node;
- }
- }
- expand(variant_node);
-
- REC_WITH_TASKS = FALSE; /* just an assumption */
- proc_init_node = build_proc_init_rec(type_name);
- CONTAINS_TASK(type_name) = (char *) REC_WITH_TASKS;
- if (proc_init_node != OPT_NODE) {
- expand(proc_init_node);
- make_insert_node(node, tup_new1((char *) copy_node(node)),
- proc_init_node);
- }
- }
- else if (nat == na_subtype) {
- N_AST3(node) = (Node)0;
- N_KIND(node) = as_subtype_decl;
- expand(node);
- }
- else if (nat == na_task_type) {
- parent_type = TYPE_OF(type_name);
- SIGNATURE(type_name) = SIGNATURE(parent_type);
- CONTAINS_TASK(type_name) = (char *) TRUE;
- }
-
- if (emap_get(type_name)) {
- delayed_node = node_new(as_declarations);
- if (emap_get(type_name))
- N_LIST(delayed_node) = EMAP_VALUE;
- expand(delayed_node);
- N_SIDE(node) |= N_SIDE(delayed_node);
- make_insert_node(node, tup_new1((char *)copy_node(node)), delayed_node);
- emap_undef(type_name);
- }
- }
-
- void expand_subtype(Node node) /*;expand_subtype*/
- {
- Node id_node, lbd_node, ubd_node, de_node, delayed_node;
- Symbol type_name, parent_type;
- Tuple field_list, constraint;
- int co_kind, i;
-
- id_node = N_AST1(node);
- type_name = N_UNQ(id_node);
- parent_type = TYPE_OF(type_name);
-
- constraint = (Tuple) get_constraint(type_name);
- co_kind = (int) constraint[1];
- if (co_kind == co_access) {
- N_SIDE(node) = FALSE;
- }
- else if (co_kind == co_range) {
- lbd_node = (Node) constraint[2];
- ubd_node = (Node) constraint[3];
- expand(lbd_node);
- expand(ubd_node);
- N_SIDE(node) = N_SIDE(lbd_node) | N_SIDE(ubd_node);
- }
- else if (co_kind == co_digits) {
- lbd_node = (Node) constraint[2];
- ubd_node= (Node) constraint[3];
- expand(lbd_node);
- expand(ubd_node);
- N_SIDE(node) = N_SIDE(lbd_node) | N_SIDE(ubd_node);
- }
- else if (co_kind == co_delta) {
- lbd_node = (Node) constraint[2];
- ubd_node = (Node) constraint[3];
- expand(lbd_node);
- expand(ubd_node);
- N_SIDE(node) = N_SIDE(lbd_node) | N_SIDE(ubd_node);
- }
- else if (co_kind == co_discr) {
- field_list = (Tuple) constraint[2];
- N_SIDE(node) = FALSE;
- /* In C, field_list is tuple with successive domain symbol
- * and range node values.
- */
- for (i = 1; i <= tup_size(field_list); i += 2) {
- de_node = (Node) field_list[i+1];
- expand(de_node);
- N_SIDE(node) |= N_SIDE(de_node);
- }
- }
- else if (co_kind == co_index) {
- N_SIDE(node) = FALSE;
- }
- else
- compiler_error_c("Unknown constraint in subtype decl: ", constraint);
-
- /* Transmit tasks_declared: */
- CONTAINS_TASK(type_name) = CONTAINS_TASK(parent_type);
-
- if (emap_get(type_name)) {
- delayed_node = node_new(as_declarations);
- N_LIST(delayed_node) = EMAP_VALUE;
- expand(delayed_node);
- N_SIDE(node) |= N_SIDE(delayed_node);
- make_insert_node(node, tup_new1((char *)copy_node(node)), delayed_node);
- emap_undef(type_name);
- }
- }
-
- void expand_attr(Node node) /*;expand_attr*/
- {
- Node precision, arg1, arg2, low_node, high_node;
- Symbol type_name, index_name, obj_name;
- Tuple index_t, tup;
- Rational delta, fx_low, fx_high, fx_ma;
- int attr, dim, discr_dep, result, i;
- int *rat_n, *rat_d; /* Multi-precision integers */
-
- Const low_const, high_const;
-
- arg1 = N_AST2(node);
- arg2 = N_AST3(node);
- attr = (int) attribute_kind(node);
-
- /* BASE attribute is evaluated to a type mark. */
- if (attr == ATTR_BASE) {
- make_name_node(node, base_type(N_UNQ(arg2)));
- }
- else {
- expand(arg1);
- }
-
- if ((arg2 != (Node)0 ? arg2: OPT_NODE) != OPT_NODE)
- expand(arg2);
-
- /* Transformations on attributes */
- switch (attr) {
- case(ATTR_O_RANGE):
- case(ATTR_O_FIRST):
- case(ATTR_O_LAST):
- case(ATTR_O_LENGTH):
-
- /* if the first parameter is a simple name, if its type is
- * constrained and, if it is an array, its bounds must no depend on
- * discriminant, then we can make a
- * conversion to an attribute to its type. This will be very useful
- * since the expansion of the T_attribute may produce some constant
- */
-
- discr_dep = FALSE;
- type_name = get_type(arg1);
- if (is_array_type(type_name)) {
- index_t = index_types(type_name);
- dim = get_ivalue_int(arg2);
- index_name = (Symbol) index_t[dim];
- tup = SIGNATURE(index_name);
- low_node = (Node) tup[2];
- high_node = (Node) tup[3];
- discr_dep = is_discr_ref(low_node) || is_discr_ref(high_node);
- }
- if (is_simple_name (arg1) && !is_unconstrained (get_type(arg1))
- && !discr_dep) {
- N_AST2 (node) = new_name_node (get_type (arg1));
- /* convert from O_ to T_ attribute by adding one */
- attribute_kind(node) = (char *) ((int)attribute_kind(node) + 1);
- expand (node);
- }
-
- #ifdef TBSL
-
- /* In case of an aggregate, the object itself declares its type and this
- * transformation leads to a RELAY_SET problem.
- */
-
- /* Transform into T_xxx of type if possible */
- type_name = get_type(arg1);
- if (is_array_type(type_name)) {
- index_t = index_types(type_name);
- dim = get_ivalue_int(arg2);
- index_name = (Symbol) index_t[dim];
- tup = SIGNATURE(index_name);
- low_node = (Node) tup[2];
- high_node = (Node) tup[3];
- discr_dep = is_discr_ref(low_node) || is_discr_ref(high_node);
- }
- else {
- discr_dep = FALSE;
- }
- if (! (discr_dep || is_unconstrained(type_name))) {
- N_KIND(arg1) = as_simple_name;
- N_AST1(arg1) = (Node)0;
- N_AST2(arg1) = (Node)0;
- N_AST3(arg1) = (Node)0;
- N_AST3(arg1) = (Node)0;
- N_UNQ(arg1) = type_name;
- N_TYPE(arg1) = type_name;
- /* convert from O_ to T_ attribute by adding one */
- attribute_kind(node) = (char *) ((int)attribute_kind(node) + 1);
- expand(node);
- }
- #endif
- break;
- case(ATTR_T_FIRST):
- type_name = N_UNQ(arg1);
- if (is_array_type(type_name)) {
- index_t = index_types(type_name);
- dim = get_ivalue_int(arg2);
- type_name = (Symbol) index_t[dim];
- }
- tup = SIGNATURE(type_name);
- low_node = (Node) tup[2];
- if (is_ivalue(low_node)) {
- copy_attributes(low_node, node);
- }
- break;
-
- case(ATTR_T_LAST):
- type_name = N_UNQ(arg1);
- if (is_array_type(type_name)) {
- index_t = index_types(type_name);
- dim = get_ivalue_int(arg2);
- type_name = (Symbol) index_t[dim];
- }
- tup = SIGNATURE(type_name);
- high_node = (Node) tup[3];
- if (is_ivalue(high_node)) {
- copy_attributes(high_node, node);
- }
- break;
-
- case(ATTR_O_CONSTRAINED):
- for (;;) {
- if (N_KIND(arg1) == as_index || N_KIND(arg1) == as_selector) {
- break;
- /* constant_folding TBSL */
- }
- else if (N_KIND(arg1) == as_all) {
- /* Allocated objects always constrained */
- make_ivalue_node(node, int_const(TRUE), symbol_boolean);
- break;
- }
- else if (N_KIND(arg1) == as_simple_name) {
- obj_name = N_UNQ(arg1);
- if (NATURE(obj_name) == na_constant
- || NATURE(obj_name) == na_in
- || ! is_unconstrained(TYPE_OF(obj_name))) {
- make_ivalue_node(node, int_const(TRUE), symbol_boolean);
- }
- break;
- }
- else {
- compiler_error("Illegal prefix for attribute");
- }
- }
- break;
-
- case(ATTR_POS):
- /* Transform into convert */
- /* Since N_AST3 and N_UNQ overlaid, clear N_AST3 field if
- * currently defined.
- */
- if (N_AST3_DEFINED(N_KIND(node))) {
- N_AST3(node) = (Node)0;
- }
- N_KIND(node) = as_convert;
- N_AST1(node) = arg1;
- N_AST2(node) = arg2;
- break;
-
- case(ATTR_COUNT):
- /*This attribute is only allowed within the body of T (9.9(5)) */
- N_AST1(arg1) = OPT_NODE;
- break;
-
- case(ATTR_O_SIZE):
- /* apply it to type of prefix. */
- /* type_name = get_type(arg1);
- * make_name_node(arg1, type_name);
- * attribute_kind(node) = (char *) ATTR_T_SIZE;
- */
- break;
-
- case(ATTR_WIDTH):
-
- type_name = N_UNQ(arg1);
- if (is_static_type(type_name)) {
- int low_int, high_int, ivalue_int;
- tup = SIGNATURE(type_name);
- low_node = (Node) tup[2];
- high_node = (Node) tup[3];
- low_const = get_ivalue (low_node);
- high_const = get_ivalue (high_node);
-
- /* this following test has been added because the bounds of the
- * range may be not static. In the previous version there was an
- * error during the get_ivalue_int. Some optimizations can still
- * be performed since we just generate the WIDTH attribute
- */
-
- if (low_const->const_kind != CONST_OM
- && high_const->const_kind != CONST_OM) {
- low_int = get_ivalue_int(low_node);
- high_int = get_ivalue_int(high_node);
- if (is_integer_type(type_name)) {
- if (low_int > high_int)
- result = 0;
- else {
- char *val_str = emalloct(10, "expand-attr-wid-1");
- low_int = abs (low_int);
- high_int = abs (high_int);
- ivalue_int = (low_int > high_int ? low_int : high_int);
- sprintf(val_str, " %d", ivalue_int);
- ivalue_int = strlen(val_str);
- efreet(val_str, "expand-attr-wid-2");
- result = ivalue_int;
- }
- }
- else { /* Enumeration types */
- int len, v;
- tup = (Tuple) literal_map(root_type(type_name));
- ivalue_int = 0;
- for (i = 1; i <= tup_size(tup); i += 2) {
- len = strlen(tup[i]);
- v = (int) tup[i+1];
- if (len > ivalue_int && (v >= low_int && v <=high_int))
- ivalue_int = len;
- }
- result = ivalue_int;
- }
- make_ivalue_node(node, int_const(result), symbol_integer);
- }
- }
- break;
-
- /* The minimum number of characters needed for the integer
- * part of the decimal representation (including sign).
- */
- case(ATTR_FORE):
- tup = SIGNATURE(N_UNQ(arg1));
- low_node = (Node) tup[2];
- high_node = (Node) tup[3];
- if (is_ivalue(low_node) && is_ivalue(high_node)) {
- fx_low = RATV((Const)N_VAL(low_node));
- fx_high = RATV((Const) N_VAL(high_node));
- if (rat_geq(rat_abs(fx_high), rat_abs(fx_low)))
- fx_ma = rat_abs(fx_high);
- else
- fx_ma = rat_abs(fx_low);
- rat_n = num(fx_ma);
- rat_d = den(fx_ma);
- result = 2;
- while (int_geq(int_quo(rat_n , rat_d) , ivalue_10)) {
- rat_d = int_mul(rat_d, ivalue_10);
- result += 1;
- }
- make_ivalue_node(node, int_const(result), symbol_integer);
- }
- break;
-
- /* The number of decimal digits needed after the decimal point
- * = smallest n such that (10**N)*FX'DELTA >= 1.0
- */
- case(ATTR_AFT):
- tup = SIGNATURE(N_UNQ(arg1));
- low_node = (Node) tup[2];
- high_node = (Node) tup[3];
- precision = (Node) tup[4];
- delta = RATV((Const) N_VAL(precision));
- fx_low = RATV((Const)N_VAL(low_node));
- fx_high = RATV((Const) N_VAL(high_node));
- result = 1;
- while (rat_lss(delta, rat_fri(int_fri(1), int_fri(10)) )){
- delta = rat_mul(delta, rat_fri(int_fri(10), int_fri(1)));
- result += 1;
- }
- make_ivalue_node(node, int_const(result), symbol_integer);
- break;
-
- case(ATTR_SAFE_LARGE):
- /* Equal to 'large of base type. */
- N_UNQ(arg1) = base_type(N_UNQ(arg1));
- attribute_kind(node) = (char *)ATTR_LARGE;
- break;
-
- case(ATTR_SAFE_SMALL):
- /* Equal to 'small of base type. */
- N_UNQ(arg1) = base_type(N_UNQ(arg1));
- attribute_kind(node) = (char *)ATTR_SMALL;
- break;
- }
-
- N_SIDE(node) = FALSE;
- }
-
- void expand_string(Node node) /*;expand_string*/
- {
- Node lbd_node, ubd_node, check_node, range_lbd_node, range_ubd_node,
- base_lbd_node;
- Symbol str_type, comp_type, new_type, indx_type, base_index_type;
- Tuple ntup, stmts_list, tup, decls;
- int str_len, lowest_char, highest_char, n, ubd_val_int, lbd, ubd, i;
- Const hg_val, lw_val;
-
- str_type = N_TYPE(node);
- str_len = tup_size((Tuple) N_VAL(node));
- if (str_len != 0) {
- /* SETL has lowest_char=MAX/...highest_char = MIN ... !! - we fix this*/
- ntup = (Tuple) N_VAL(node);
- lowest_char = (int) ntup[1];
- highest_char = (int) ntup[1];
- n = tup_size(ntup);
- for (i = 2; i <= n; i++) {
- if ((int)ntup[i] < lowest_char) lowest_char = (int) ntup[i];
- if ((int)ntup[i] > highest_char) highest_char = (int) ntup[i];
- }
- /*lowest_char = max/N_VAL(node); !!*/
- /*highest_char = min/N_VAL(node); !!*/
- comp_type = (Symbol) component_type(str_type);
- stmts_list = tup_new(0);
- tup = SIGNATURE(comp_type);
- lbd_node = (Node) tup[2];
- ubd_node = (Node) tup[3];
-
- lw_val = get_ivalue(lbd_node);
- if (lw_val->const_kind != CONST_OM) {
- if (lowest_char < get_ivalue_int(lbd_node)) {
- make_raise_node(node, symbol_constraint_error);
- USER_WARNING("Character in string will raise ",
- " CONSTRAINT_ERROR");
- }
- }
- else {
- check_node = node_new(as_discard);
- N_AST1(check_node) = new_qual_range_node( new_ivalue_node(
- int_const(lowest_char), symbol_character), comp_type);
- N_TYPE(check_node) = comp_type;
- N_SIDE(check_node) = FALSE;
- stmts_list = tup_new1((char *) check_node);
- }
- hg_val = get_ivalue(ubd_node);
- if (hg_val->const_kind != CONST_OM) {
- if (highest_char > get_ivalue_int(ubd_node)) {
- make_raise_node(node, symbol_constraint_error);
- USER_WARNING("Character in string will raise ",
- "CONSTRAINT_ERROR");
- }
- }
- else {
- check_node = node_new(as_discard);
- N_AST1(check_node) = new_qual_range_node( new_ivalue_node(
- int_const(highest_char), symbol_character), comp_type);
- N_TYPE(check_node) = comp_type;
- N_SIDE(check_node) = FALSE;
- stmts_list = tup_with(stmts_list, (char *) check_node);
- }
- if (tup_size(stmts_list) != 0) {
- make_insert_node(node, stmts_list, copy_node(node));
- node = N_AST1(node);
- N_SIDE(node) = FALSE;
- }
- }
-
- /* construct subtype */
-
- tup = index_types(str_type);
- indx_type = (Symbol) tup[1];
- tup = SIGNATURE(indx_type);
- lbd_node = (Node) tup[2];
- ubd_node = (Node) tup[3];
- if (is_ivalue(lbd_node)) {
- lbd = get_ivalue_int(lbd_node);
- base_index_type = base_type(indx_type);
- tup = SIGNATURE(base_index_type);
- base_lbd_node = (Node) tup[2];
- if (str_len == 0
- && const_eq(get_ivalue(lbd_node), get_ivalue(base_lbd_node))) {
- /* LRM 4.2(3) */
- make_raise_node(node, symbol_constraint_error);
- USER_WARNING("Null string will raise CONSTRAINT_ERROR",
- " (LRM 4.2(3))" );
- }
- else {
- ubd_val_int = lbd + str_len - 1;
- if (is_ivalue(ubd_node)) {
- ubd = get_ivalue_int(ubd_node);
- if (!is_unconstrained(str_type)) {
- if ((str_len != 0 && ubd_val_int != ubd)
- || (str_len == 0 && ubd >= lbd)) {
- make_raise_node(node, symbol_constraint_error);
- USER_WARNING("String literal will raise ",
- "CONSTRAINT_ERROR");
- }
- else return; /* static bounds ok. */
- }
- else { /* unconstrained context. Length may be too big. */
- if (ubd_val_int > ubd) {
- make_raise_node(node, symbol_constraint_error);
- USER_WARNING("String literal will raise ",
- "CONSTRAINT_ERROR");
- }
- }
- }
- /* else gen_subtype will emit a qual sub */
- }
- range_lbd_node = copy_node(lbd_node);
- range_ubd_node = new_ivalue_node(int_const(ubd_val_int),
- N_TYPE(range_lbd_node));
- }
- else { /* lbd_node is not an ivalue */
- /* write range_lbd_node as an attribute node */
- range_lbd_node = new_attribute_node(ATTR_T_FIRST,
- new_name_node(indx_type), OPT_NODE, indx_type);
- range_ubd_node = new_binop_node(symbol_addi, range_lbd_node,
- new_ivalue_node(int_const(str_len-1), base_type(indx_type)),
- base_type(indx_type));
- /* gen_subtype will emit a qual sub on the index type */
- }
-
- if (N_KIND(node) != as_raise) {
- tup = constrained_type(str_type, range_lbd_node, range_ubd_node);
- new_type = (Symbol) tup[1];
- decls = (Tuple) tup[2];
- N_TYPE(node) = new_type;
- N_SIDE(node) = FALSE;
- make_insert_node(node, decls, copy_node(node));
- }
- N_SIDE(node) = FALSE;
- }
-
- void expand_op(Node node) /*;expand_op*/
- {
- Node op_node, args_node, arg1, arg2, conv_node, to_type_node, type_node,
- lbd_node, ubd_node, constraint_node, lbd_node1, ubd_node1;
- Symbol op_name, range_name, type_name;
- Symbol indx_t, str1_type;
- Tuple tup, constraint;
- Node comp;
-
- op_node = N_AST1(node);
- args_node = N_AST2(node);
- op_name = N_UNQ(op_node);
- arg1 = (Node) ((Tuple)N_LIST(args_node) [1]);
- arg2 = (Node) ((Tuple)N_LIST(args_node) [2]);
-
- /* Constant folding: concatenation of two non-null string which index_type
- * is static.
- */
- if (op_name == symbol_cat && N_KIND(arg1) == as_string_ivalue
- && N_KIND(arg2) == as_string_ivalue ) {
- str1_type = N_TYPE(arg1);
- indx_t = (Symbol) index_types(str1_type)[1];
- tup = SIGNATURE(indx_t);
- lbd_node1 = (Node) tup[2];
- ubd_node1 = (Node) tup[3];
- /* if the index_type is static and the length of both the strings
- * is not null, then we transform the node into a string_ivalue
- * which is the concatenation of the two strings.
- */
- if (N_KIND(lbd_node1) == as_ivalue && N_KIND(ubd_node1) == as_ivalue
- && tup_size((Tuple) N_VAL(arg1)) &&tup_size((Tuple) N_VAL(arg2))) {
- N_KIND(node) = as_string_ivalue;
- N_AST1(node) = N_AST2(node) = N_AST3(node) = N_AST4(node) = (Node)0;
- N_VAL(node) = (char *) tup_add((Tuple)N_VAL(arg1),
- (Tuple)N_VAL(arg2));
- N_TYPE(node) = str1_type;
- expand(node); /* and generate subtype, etc. */
- }
- }
-
- /* case of the new catenation instructions */
-
- else if (op_name == symbol_cat_ca) {
- comp = copy_node (arg1);
- N_KIND (arg1) = as_row;
- N_AST1 (arg1) = comp;
- N_AST2 (arg1) = (Node) 0;
- N_TYPE (arg1) = N_TYPE (node);
- N_UNQ (N_AST1(node)) = symbol_cat;
- }
- else if (op_name == symbol_cat_ac) {
- comp = copy_node (arg2);
- N_KIND (arg2) = as_row;
- N_AST1 (arg2) = comp;
- N_AST2 (arg2) = (Node) 0;
- N_TYPE (arg2) = N_TYPE (node);
- N_UNQ (N_AST1(node)) = symbol_cat;
- }
- else if (op_name == symbol_cat_cc) {
- comp = copy_node (arg2);
- N_KIND (arg2) = as_row;
- N_AST1 (arg2) = comp;
- N_AST2 (arg2) = (Node) 0;
- N_TYPE (arg2) = N_TYPE (node);
-
- comp = copy_node (arg1);
- N_KIND (arg1) = as_row;
- N_AST1 (arg1) = comp;
- N_AST2 (arg1) = (Node) 0;
- N_TYPE (arg1) = N_TYPE (node);
-
- N_UNQ (N_AST1(node)) = symbol_cat;
- }
- /* Transform some operations: */
- else if (op_name == symbol_mulfli || op_name == symbol_divfli) {
- conv_node = node_new(as_convert);
- to_type_node = new_name_node(symbol_universal_real);
- N_AST1(conv_node) = to_type_node;
- N_AST2(conv_node) = arg2;
- N_TYPE(conv_node) = symbol_universal_real;
- arg2 = conv_node;
- tup = tup_new(2);
- tup[1] = (char *) arg1;
- tup[2] = (char *) arg2;
- N_LIST(args_node) = tup;
- N_UNQ(op_node) = (op_name == symbol_mulfli) ? symbol_mulfl
- : symbol_divfl;
- }
- else if (op_name == symbol_mulifx) {
- tup = tup_new(2);
- tup[1] = (char *) arg2;
- tup[2] = (char *) arg1;
- N_LIST(args_node) = tup;
- N_UNQ(op_node) = symbol_mulfxi;
- }
- else if (op_name == symbol_in || op_name == symbol_notin) {
- if (!is_simple_name(arg2)) {
- /* Add subtype declaration */
- range_name = new_unique_name("range");
- type_name = N_TYPE(arg2);
- if (N_KIND(arg2) == as_attribute) {
- lbd_node = copy_node(arg2);
- ubd_node = copy_tree(arg2);
- /*lbd_attr_node = N_AST1(lbd_node); -- not needed in C version*/
- /*ubd_attr_node = N_AST1(ubd_node); -- not needed in C version*/
- if ((int) attribute_kind(lbd_node) == ATTR_T_RANGE) {
- attribute_kind(lbd_node) = (char *) ATTR_T_FIRST;
- attribute_kind(ubd_node) = (char *)ATTR_T_LAST;
- }
- else { /* 'O_RANGE' */
- attribute_kind(lbd_node) = (char *) ATTR_O_FIRST;
- attribute_kind(ubd_node) = (char *) ATTR_O_LAST;
- }
- constraint = constraint_new(co_range);
- constraint[2] = (char *) lbd_node;
- constraint[3] = (char *) ubd_node;
- }
- else { /* as_subtype */
- Tuple t;
-
- constraint_node = N_AST2(arg2);
- lbd_node = N_AST1(constraint_node);
- ubd_node = N_AST2(constraint_node);
-
- t = SIGNATURE(type_name);
- constraint = constraint_new((int)numeric_constraint_kind(t));
- numeric_constraint_low(constraint) = (char *) lbd_node;
- numeric_constraint_high(constraint) = (char *) ubd_node;
-
- /* inherit precision of real subtype from parent type */
- if (numeric_constraint_kind(t) == (char *)co_digits) {
- numeric_constraint_digits(constraint) =
- numeric_constraint_digits(t);
- }
- else if (numeric_constraint_kind(t) == (char *)co_delta) {
- numeric_constraint_delta(constraint) =
- numeric_constraint_delta(t);
- numeric_constraint_small(constraint) =
- numeric_constraint_small(t);
- }
- }
- NATURE(range_name) = na_subtype;
- TYPE_OF(range_name) = base_type(type_name);
- SIGNATURE(range_name) = constraint;
- ALIAS(range_name) = ALIAS(type_name);
- type_node = node_new(as_subtype_decl);
- N_AST1(type_node) = new_name_node(range_name);
- make_insert_node(node,tup_new1((char *)type_node), copy_node(node));
- make_name_node(arg2, range_name);
- }
- }
-
- expand(arg1);
- expand(arg2);
- N_SIDE(node) = N_SIDE(arg1) | N_SIDE(arg2);
- }
-
- void expand_for(Node node) /*;expand_for*/
- {
- Node id_node, range_node, low_node, high_node, ubd_node, lbd_node,
- arg1, arg2, type_node, new_range_node, decl_node;
- Symbol type_name, type_mark;
- Const lbd, ubd, low_const, high_const;
- Tuple tup;
- int nk, attr_prefix;
-
- id_node = N_AST1(node);
- range_node = N_AST2(node);
- nk = N_KIND(range_node);
- if (nk == as_subtype){
- type_node = N_AST1(range_node);
- type_mark = N_UNQ(type_node);
- new_range_node = N_AST2(range_node);
- low_node = N_AST1(new_range_node);
- high_node = N_AST2(new_range_node);
- type_name = new_unique_name("loop_type");
- tup = constraint_new(co_range);
- tup[2] = (char *) low_node;
- tup[3] = (char *) high_node;
- new_symbol(type_name, na_subtype, type_mark, tup, ALIAS(type_mark));
- if (not_included(type_name, type_mark) ) {
- decl_node = new_subtype_decl_node(type_name);
- expand(decl_node);
- make_insert_node(node,tup_new1((char *)decl_node), copy_node(node));
- node = N_AST1(node);
- type_node = new_name_node(type_name);
- low_node = new_attribute_node(ATTR_T_FIRST, type_node, OPT_NODE,
- type_name);
- high_node = new_attribute_node(ATTR_T_LAST, type_node, OPT_NODE,
- type_name);
- }
- else {
- /* we don't need type_name*/
- new_symbol(type_name, na_void, (Symbol)0, (Tuple)0, (Symbol)0);
- }
- }
- else if (nk == as_range) {
- low_node = N_AST1(range_node);
- high_node = N_AST2(range_node);
- }
- else if (nk == as_name) {
- range_node = N_AST1(range_node);
- type_name = N_UNQ(range_node);
- tup = get_constraint(type_name);
- low_node = (Node) tup[2];
- high_node = (Node) tup[3];
- if (!is_ivalue(low_node) || !is_ivalue(high_node)) {
- low_node = new_attribute_node(ATTR_T_FIRST,
- copy_node(range_node), OPT_NODE, type_name);
- high_node= new_attribute_node(ATTR_T_LAST,
- copy_node(range_node), OPT_NODE, type_name);
- }
- }
- else if (nk == as_simple_name) {
- type_name = N_UNQ(range_node);
- tup = get_constraint(type_name);
- low_node = (Node) tup[2];
- high_node = (Node) tup[3];
- if (!is_ivalue(low_node) || !is_ivalue(high_node)) {
- low_node = new_attribute_node(ATTR_T_FIRST,
- copy_node(range_node), OPT_NODE, type_name);
- high_node= new_attribute_node(ATTR_T_LAST,
- copy_node(range_node), OPT_NODE, type_name);
- }
- }
- else if (nk == as_attribute) {
- /*att_node = N_AST1(range_node);*/
- arg1 = N_AST2(range_node);
- arg2 = N_AST3(range_node);
- attr_prefix = (int)attribute_kind(range_node)-ATTR_RANGE;
- /* 'T' or 'O'*/
- attribute_kind(range_node) = (char *) ((int)attr_prefix + ATTR_FIRST);
- low_node = range_node;
- high_node = new_attribute_node(attr_prefix + ATTR_LAST,
- copy_node(arg1), copy_node(arg2), get_type(range_node));
- }
- else {
- compiler_error_k("Unexpected range in for: ", range_node );
- low_node = high_node = OPT_NODE;
- }
- expand(low_node);
- expand(high_node);
- low_const = get_ivalue(low_node);
- high_const = get_ivalue(high_node);
- tup = get_constraint(get_type(range_node));
- lbd_node = (Node) tup[2];
- ubd_node = (Node)tup[3];
- if (low_const->const_kind != CONST_OM
- && high_const->const_kind != CONST_OM
- && get_ivalue_int(high_node) < get_ivalue_int(low_node) ) {
- /* static null range */
- delete_node(node);
- }
- else {
- lbd = get_ivalue(lbd_node);
- ubd = get_ivalue(ubd_node);
- if (low_const->const_kind != CONST_OM
- && high_const->const_kind != CONST_OM
- && lbd->const_kind != CONST_OM
- && ubd->const_kind != CONST_OM
- && (get_ivalue_int(lbd_node) > get_ivalue_int(low_node)
- || get_ivalue_int(ubd_node) < get_ivalue_int(high_node))) {
- /* static violation of constraints */
- make_raise_node(node, symbol_constraint_error);
- USER_WARNING("Evaluation of range will raise",
- " CONSTRAINT_ERROR");
- }
- else {
- N_AST1(node) = id_node;
- N_AST2(node) = low_node;
- N_AST3(node) = high_node;
- }
- }
- }
-